package merger;

import java.util.List;
import java.util.Set;

import util.XMLParser;
import util.XMLParser.Relation;

import com.lemon.ai.socket.packets.spiritgame.db.utils.KeyUtil;
import com.lemon.ai.socket.packets.spiritgame.db.utils.Mapping;

/**
 * 冲突处理器
 * @author 	林岑
 * @time	2012年9月6日 16:47:47
 */
public class Collides {

	private static final XMLParser XL = XMLParser.getInstance();
	
	/**
	 * 取消ds1和ds2的主键冲突, 该方法执行完后, 变化的只有ds2, 而ds1原封不动
	 * @param ds1
	 * @param ds2
	 */
	public static void cancelCollides(Datas ds1, Datas ds2) {
		for (String table : Mapping.getAllTableName()) {
			for (String column : Mapping.getColumns(table)) {
				if(XL.contains(table + "." + column)) {
					Relation r = XL.getRelation(table + "." + column);
					process(table, r.henchmans, ds1, ds2);
				}
			}
		}
	}

	/**
	 * 将ds2中的table.column数值变得跟ds1无冲突,  
	 * 改变table.column同时改变ds2中henchmans所有对应的列
	 *
	 * @param table			表名T
	 * @param column		列名C
	 * @param henchmans		所有跟随T.C变化的列,  格式: TableName.ColumnName
	 * @param ds1			待对比的数据库
	 * @param ds2			将要发生变化的数据库
	 */
	private static void process(String table, Set<String> henchmans, Datas ds1, Datas ds2) {

		List<?> l1 = ds1.all.get(table);
		List<?> l2 = ds2.all.get(table);
		
		for (Object o : l2) {
			if(keyIsIn(o, l1, l2)) {
				changeKey(l1, l2, o);
			}
		}
	}

	/**
	 * 重置键, 让o的键和l1 , l2中的都不冲突
	 * @param l1
	 * @param l2
	 * @param o
	 */
	private static void changeKey(List<?> l1, List<?> l2, Object o) {
		
		KeyUtil.changeKey(l1, l2, o);
		
		if(keyIsIn(o, l1, l2)) {
			throw new RuntimeException("键冲突未处理完" + KeyUtil.getKey(o));
		}
	}

	/**
	 * 判断o 的主键是不是和l1 l2中对应对象的key发生冲突
	 * @param 对象
	 * @return
	 */
	private static boolean keyIsIn(Object o, List<?> l1, List<?> l2) {
		for (Object oInl : l1) 
			if(KeyUtil.isKeyEqual(o, oInl)) 
				return true;
		
		for (Object oInl2 : l2) 
			if(KeyUtil.isKeyEqual(o, oInl2)) 
				return true;
		
		return false;
	}
}
